package tas.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import tas.dao.DaoAsistencia;
import tas.sql.ConectaDb;

public class DaoAsistenciaImpl implements DaoAsistencia {

    private final ConectaDb db;

    public DaoAsistenciaImpl() {
        this.db = new ConectaDb();
    }

    @Override
    public Object[] asistenciaAhora() {
        Object[] ahora = null;
        String sql = "SELECT "
                + "TO_CHAR((SELECT SYSDATE FROM DUAL), 'DD/MM/YYYY' ) fecha,"
                + "TO_CHAR((SELECT SYSDATE FROM DUAL), 'HH:MI:SS' ) hora "
                + "FROM DUAL";

        Connection cn = db.getBdtas();
        if (cn != null) {
            try {
                PreparedStatement ps = cn.prepareStatement(sql);
                ResultSet rs = ps.executeQuery();

                if (rs.next()) {
                    ahora = new Object[2];

                    ahora[0] = rs.getObject(1); // fecha
                    ahora[1] = rs.getObject(2); // hora
                }

            } catch (SQLException e) {
                System.out.println("");
            } finally {
                try {
                    cn.close();
                } catch (SQLException e) {
                }
            }
        }

        return ahora;
    }

    @Override
    public String asistenciaAhoraIns(Integer idtrabajador, String fecha, String hora, Integer idusuario, String IP, String PC, String observacion) {
        String result = null;

        String sql01 = "SELECT "
                + "NVL(MAX(IDCORRELATIVO), 0) + 1 AS NIDCORRELATIVO "
                + "FROM BDTAS.MARCACION "
                + "WHERE IDTRABAJADOR=? "
                + "AND IDFECHA=TO_DATE(?, 'DD/MM/YYYY') "
                + "AND IDHORA=TO_TIMESTAMP(?, 'HH24:MI:SS')";

        String sql02 = "INSERT INTO BDTAS.MARCACION("
                + "IDTRABAJADOR,"
                + "IDFECHA,"
                + "IDHORA,"
                + "IDCORRELATIVO,"
                + "IDMARCACIONTIPO,"
                + "IDESTADO"
                + ") VALUES("
                + "?," // idtrabajador
                + "TO_DATE(?, 'DD/MM/YYYY')," // fecha
                + "TO_TIMESTAMP(?, 'HH24:MI:SS')," // hora
                + "?," // NIDCORRELATIVO (select en sql01)
                + "1," // FIJO INDICA QUE LA MARCACIÓN ES POR WEB
                + "1)"; // FIJO INDICA QUE ESTADO ACTIVO

        String sql03 = "INSERT INTO BDTAS.MARCACIONWEB("
                + "IDTRABAJADOR,"
                + "IDFECHA,"
                + "IDHORA,"
                + "IDCORRELATIVO,"
                + "IDUSUARIO,"
                + "IP,"
                + "PC,"
                + "OBSERVACION"
                + ") VALUES("
                + "?," // idtrabajador
                + "TO_DATE(?, 'DD/MM/YYYY')," // fecha
                + "TO_TIMESTAMP(?, 'HH24:MI:SS')," // hora
                + "?," // NIDCORRELATIVO (select en sql01)
                + "?," // idtrabajador
                + "?," // ip de la PC del usuario
                + "?," // nombre de la PC del usuario 
                + "?)";

        Connection cn = db.getBdtas();
        if (cn != null) {
            boolean ok = false;
            try {
                cn.setAutoCommit(false);

                // generar correlativo
                PreparedStatement ps = cn.prepareStatement(sql01);
                ps.setInt(1, idtrabajador);
                ps.setString(2, fecha);
                ps.setString(3, hora);

                ResultSet rs = ps.executeQuery();

                Integer nidcorrelativo = null;
                if (rs.next()) {
                    nidcorrelativo = rs.getInt(1);
                } else {
                    throw new SQLException("Error al generar Correlativo");
                }
                ps.close();

                // insertar asistencia
                ps = cn.prepareStatement(sql02);
                ps.setInt(1, idtrabajador);
                ps.setString(2, fecha);
                ps.setString(3, hora);
                ps.setInt(4, nidcorrelativo);

                int ctos = ps.executeUpdate();
                if (ctos == 0) {
                    result = "No se pudo registrar Asistencia";
                    throw new SQLException(result);
                }
                ps.close();

                // insertar asistencia web
                ps = cn.prepareStatement(sql03);
                ps.setInt(1, idtrabajador);
                ps.setString(2, fecha);
                ps.setString(3, hora);
                ps.setInt(4, nidcorrelativo);
                ps.setInt(5, idusuario);
                ps.setString(6, IP);
                ps.setString(7, PC);
                ps.setString(8, observacion);

                ctos = ps.executeUpdate();
                if (ctos == 0) {
                    result = "No se pudo registrar Asistencia Web";
                    throw new SQLException(result);
                }
                ps.close();

                ok = true;

            } catch (SQLException e) {
                result = e.getMessage();
            } finally {
                try {
                    if (ok) {
                        cn.commit();
                    } else {
                        cn.rollback();
                    }

                    cn.setAutoCommit(true);
                    cn.close();

                } catch (SQLException e) {
                    result = e.getMessage();
                }
            }
        }

        return result;
    }

    @Override
    public List<Object[]> asistenciaCon(Integer idtrabajador, String idfecha, long numpag, long filsXpag) {
        List<Object[]> list = null;
        String sql = "SELECT * FROM " // adicional a consulta
                + "(SELECT rownum rnum, a.* FROM ( " // adicional a consulta
                + "SELECT "
                + "TO_CHAR(MAR.IDFECHA, 'DD/MM/YYYY' ) FECHA,"
                + "TO_CHAR(MAR.IDHORA, 'HH:MI:SS' ) HORA,"
                + "MARTIP.DESCRIPCION TIPOMARCACION,"
                + "MARWEB.IP IP,"
                + "MARWEB.PC PC,"
                + "USU.APELLIDOS || ' ' || USU.NOMBRES USUARIO "
                + "FROM BDTAS.MARCACION MAR "
                + "LEFT JOIN BDTAS.MARCACIONTIPO MARTIP "
                + "ON (MAR.IDMARCACIONTIPO=MARTIP.IDMARCACIONTIPO) "
                + "LEFT JOIN BDTAS.MARCACIONWEB MARWEB "
                + "ON (MARWEB.IDTRABAJADOR=MAR.IDTRABAJADOR "
                + "AND MARWEB.IDFECHA=MAR.IDFECHA "
                + "AND MARWEB.IDHORA=MAR.IDHORA "
                + "AND MARWEB.IDCORRELATIVO=MAR.IDCORRELATIVO) "
                + "LEFT JOIN BDTAS.USUARIOS USU "
                + "ON (USU.IDUSUARIO = MARWEB.IDUSUARIO) "
                + "WHERE  MAR.IDESTADO=1 "
                + "AND MAR.IDTRABAJADOR=? "
                + "AND TO_CHAR(MAR.IDFECHA, 'YYYYMM')= ? "
                + "ORDER BY 1,2"
                + ") a WHERE rownum <= ?) " // adicional a consulta
                + "WHERE rnum > ?"; // adicional a consulta;

        Connection cn = db.getBdtas();
        if (cn != null) {
            try {
                PreparedStatement ps = cn.prepareStatement(sql);
                ps.setInt(1, idtrabajador);
                ps.setString(2, idfecha);
                ps.setLong(3, ((1 + numpag) * filsXpag));
                ps.setLong(4, (numpag * filsXpag));

                ResultSet rs = ps.executeQuery();

                list = new LinkedList<Object[]>();
                while (rs.next()) {
                    Object[] f = new Object[6];

                    f[0] = rs.getObject(1); // FECHA
                    f[1] = rs.getObject(2); // HORA
                    f[2] = rs.getObject(3); // TIPOMARCACION
                    f[3] = rs.getObject(4); // IP
                    f[4] = rs.getObject(5); // PC
                    f[5] = rs.getObject(6); // USUARIO

                    list.add(f);
                }

            } catch (SQLException e) {
            } finally {
                try {
                    cn.close();
                } catch (SQLException e) {
                }
            }
        }

        return list;
    }

        @Override
    public Integer[] asistenciaConPag(Integer idtrabajador, String idfecha, long filsXpag) {
        Integer[] result = null;
        String sql = "SELECT COUNT(*) "
                + "FROM BDTAS.MARCACION MAR "
                + "LEFT JOIN BDTAS.MARCACIONTIPO MARTIP "
                + "ON (MAR.IDMARCACIONTIPO=MARTIP.IDMARCACIONTIPO) "
                + "LEFT JOIN BDTAS.MARCACIONWEB MARWEB "
                + "ON (MARWEB.IDTRABAJADOR=MAR.IDTRABAJADOR "
                + "AND MARWEB.IDFECHA=MAR.IDFECHA "
                + "AND MARWEB.IDHORA=MAR.IDHORA "
                + "AND MARWEB.IDCORRELATIVO=MAR.IDCORRELATIVO) "
                + "LEFT JOIN BDTAS.USUARIOS USU "
                + "ON (USU.IDUSUARIO = MARWEB.IDUSUARIO) "
                + "WHERE  MAR.IDESTADO=1 "
                + "AND MAR.IDTRABAJADOR=? "
                + "AND TO_CHAR(MAR.IDFECHA, 'YYYYMM')= ?";

        Connection cn = db.getBdtas();
        if (cn != null) {
            try {
                PreparedStatement ps = cn.prepareStatement(sql);
                ps.setInt(1, idtrabajador);
                ps.setString(2, idfecha);

                ResultSet rs = ps.executeQuery();

                if (rs.next()) {
                    // total filas de consulta
                    Integer totalfils = rs.getInt(1);

                    // cantidad de paginas con filsXpag
                    Integer ctasPags = (totalfils % filsXpag) == 0
                            ? (totalfils / (int)filsXpag)
                            : (totalfils / (int)filsXpag + 1);

                    result = new Integer[2];
                    result[0] = ctasPags;
                    result[1] = totalfils;
                }

            } catch (SQLException e) {
            } finally {
                try {
                    cn.close();
                } catch (SQLException e) {
                }
            }
        }

        return result;
    }
    
    @Override
    public List<Object[]> asistenciaQry(String filtro) {
        List<Object[]> list = null;
        String sql = "SELECT "
                + "TRA.IDTRABAJADOR,"
                + "TRA.APELLIDOPATERNO   ||  ' ' ||  TRA.APELLIDOMATERNO AS APELLIDOS,"
                + "TRA.NOMBRE,"
                + "tipdoc.descripciontipodocumento ||  '-' ||  TRA.NUMERODOCUMENTOIDENTIDAD AS DOCUMENTO "
                + "FROM BDTAS.TRABAJADOR TRA "
                + "LEFT JOIN  BDTAS.TRABAJADORPJ TRAPJ "
                + "ON  (TRA.IDTRABAJADOR = TRAPJ.IDTRABAJADOR) "
                + "LEFT JOIN BDTAS.TIPODOCUMENTO TIPDOC "
                + "ON (TIPDOC.IDTIPODOCUMENTO=TRA.IDTIPODOCUMENTO) "
                + "LEFT JOIN BDTAS.HORARIO HOR "
                + "ON (HOR.IDHORARIO=TRA.IDHORARIOVIGENTE) "
                + "WHERE " + filtro;

        Connection cn = db.getBdtas();
        if (cn != null) {
            try {
                PreparedStatement ps = cn.prepareStatement(sql);
                ResultSet rs = ps.executeQuery();

                list = new LinkedList<Object[]>();
                while (rs.next()) {
                    Object[] f = new Object[4];

                    f[0] = rs.getObject(1); // IDTRABAJADOR
                    f[1] = rs.getObject(2); // APELLIDOS
                    f[2] = rs.getObject(3); // NOMBRE
                    f[3] = rs.getObject(4); // DOCUMENTO

                    list.add(f);
                }

            } catch (SQLException e) {
            } finally {
                try {
                    cn.close();
                } catch (SQLException e) {
                }
            }
        }

        return list;
    }

    @Override
    public String fechaSistema() {
        String fecha = null;
        String sql = "select TO_CHAR((SELECT SYSDATE FROM DUAL), 'DD/MM/YYYY' ) from dual";

        Connection cn = db.getBdtas();
        if (cn != null) {
            try {
                PreparedStatement ps = cn.prepareStatement(sql);
                ResultSet rs = ps.executeQuery();

                if (rs.next()) {
                    fecha = rs.getString(1);
                }

            } catch (SQLException e) {
            } finally {
                try {
                    cn.close();
                } catch (SQLException e) {
                }
            }
        }

        return fecha;
    }

    @Override
    public String marcaMasiva(Integer idusuario, String fecha, List<Integer> idtrabajador, List<String> hh, List<String> mm, String IP, String PC, List<String> obs) {
        String result = null;

        Connection cn = db.getBdtas();

        boolean ok = false;

        for (int i = 0; i < idtrabajador.size(); i++) {
            Integer _idtrab = (Integer) idtrabajador.get(i);
            String _hh = (String) hh.get(i);
            String _mm = (String) mm.get(i);
            String _hhmm = _hh + _mm;

            String _obs = (String) obs.get(i);

            // INSERT MARCACION
            // public String asistenciaAhoraIns(Integer idtrabajador, String fecha, String hora, String IP, String PC) {
            result = asistenciaAhoraIns(_idtrab, fecha, _hhmm, idusuario, IP, PC, _obs);
        }

        ok = true;

        return result;
    }

    @Override
    public List<Object[]> marcaConsulta(Integer idtrabajador, String periodo) {
        List<Object[]> list = null;
        String sql = "SELECT "
                + "TO_CHAR(MAR.IDFECHA, 'DD/MM/YYYY' ) FECHA,"
                + "TO_CHAR(MAR.IDHORA, 'HH:MI:SS' ) HORA,"
                + "MARTIP.DESCRIPCION TIPOMARCACION,"
                + "USU.APELLIDOS || ' ' || USU.NOMBRES USUARIO "
                + "FROM BDTAS.MARCACION MAR "
                + "LEFT JOIN BDTAS.MARCACIONTIPO MARTIP "
                + "ON (MAR.IDMARCACIONTIPO=MARTIP.IDMARCACIONTIPO) "
                + "LEFT JOIN BDTAS.MARCACIONWEB MARWEB "
                + "ON (MARWEB.IDTRABAJADOR=MAR.IDTRABAJADOR "
                + "AND MARWEB.IDFECHA=MAR.IDFECHA "
                + "AND MARWEB.IDHORA=MAR.IDHORA "
                + "AND MARWEB.IDCORRELATIVO=MAR.IDCORRELATIVO) "
                + "LEFT JOIN BDTAS.USUARIOS USU "
                + "ON (USU.IDUSUARIO = MARWEB.IDUSUARIO) "
                + "WHERE  MAR.IDESTADO=1 "
                + "AND  MAR.IDTRABAJADOR=? "
                + "AND TO_CHAR(MAR.IDFECHA, 'YYYYMM')= ? "
                + "ORDER BY 1,2";

        Connection cn = db.getBdtas();
        if (cn != null) {
            try {
                PreparedStatement ps = cn.prepareStatement(sql);
                ps.setInt(1, idtrabajador);
                ps.setString(2, periodo);

                ResultSet rs = ps.executeQuery();

                list = new LinkedList<Object[]>();
                while (rs.next()) {
                    Object[] f = new Object[4];

                    f[0] = rs.getObject(1); // FECHA
                    f[1] = rs.getObject(2); // HORA
                    f[2] = rs.getObject(3); // TIPOMARCACION
                    f[3] = rs.getObject(4); // USUARIO

                    list.add(f);
                }

            } catch (SQLException e) {
            } finally {
                try {
                    cn.close();
                } catch (SQLException e) {
                }
            }
        }

        return list;
    }

}
